package zdream.control.world.buff;

import zdream.control.input.WorldInput;
import zdream.control.world.MFoe;
import zdream.control.world.MFoeBuff;
import zdream.control.world.MHookType;
import zdream.control.world.MHooks;

import static zdream.control.input.WorldInput.*;

/**
 * @author Zdream
 * @since 0.0.1
 * @date 2022-05-28
 */
public class ControlModule extends MFoeBuff {
	public static final String CATEGORY = "control";

	public WorldInput input;

	private ControlModule(MFoe foe) {
		super(foe);
	}

	@Override
	public void init() {
		onHook(MHookType.TICK)
				.withPriority(-900)
				.handle(this::receiveInput)
				.buildAndSave();
	}

	@Override
	public String getCategory() {
		return CATEGORY;
	}

	/* **********
	 *   控制   *
	 ********** */

	/**
	 * 是否向左或向右移动. 左和右不会同时为 true.
	 */
	public boolean left, right;
	public boolean up, down;
	/**
	 * 两个键是否同时按下
	 */
	private boolean leftAndRight, upAndDown;
	/**
	 * 上一步, 方向键是否按下
	 */
	public boolean lastLeft, lastRight, lastUp, lastDown;
	public boolean jump, attack, slide;
	/**
	 * 上一步, 行动键位是否按下
	 */
	public boolean lastJump, lastAttack, lastSlide;

	/**
	 * <p>其它. 这些 key 的值的意义如下:
	 * <li>0: 无
	 * <li>1: 上一帧未按下, 当前按下
	 * <li>2: 上一帧按下, 当前释放
	 * <li>3: 上一帧按下, 当前一直按着
	 * </li></p>
	 */
	public byte keyProp1, keyProp2;

	private void receiveInput(MHooks.MHookContext rawContexts) {
		if (input == null) {
			return;
		}

		// 横向
		lastLeft = left;
		lastRight = right;
		lastUp = up;
		lastDown = down;
		left = input.isMapKeyDown(MAP_LEFT);
		right = input.isMapKeyDown(MAP_RIGHT);
		up = input.isMapKeyDown(MAP_UP);
		down = input.isMapKeyDown(MAP_DOWN);
		if (left && right) {
			if (!leftAndRight) {
				if (lastLeft && !lastRight) {
					left = false;
					// right = true;
				} else if (!lastLeft && lastRight) {
					// left = true;
					right = false;
				} else {
					left = right = false;
				}
			} else {
				left = lastLeft;
				right = lastRight;
			}
			leftAndRight = true;
		} else {
			leftAndRight = false;
		}
		if (up && down) {
			if (!upAndDown) {
				if (lastUp && !lastDown) {
					up = false;
					// down = true;
				} else if (!lastUp && lastDown) {
					// up = true;
					down = false;
				} else {
					up = down = false;
				}
			} else {
				up = lastUp;
				down = lastDown;
			}
			upAndDown = true;
		} else {
			upAndDown = false;
		}

		// 行动状态
		lastAttack = attack;
		lastJump = jump;
		lastSlide = slide;
		attack = input.isMapKeyDown(MAP_ATTACK);
		jump = input.isMapKeyDown(MAP_JUMP);
		slide = input.isMapKeyDown(MAP_RUSH);

		// 其它按键
		keyProp1 = (byte) (((keyProp1 << 1) | (input.isMapKeyDown(MAP_PROP1) ? 1 : 0)) & 3);
		keyProp2 = (byte) (((keyProp2 << 1) | (input.isMapKeyDown(MAP_PROP2) ? 1 : 0)) & 3);
	}

	public static ControlModuleFactory builder(MFoe foe) {
		return new ControlModuleFactory(foe);
	}

	public static class ControlModuleFactory {
		ControlModule module;
		public ControlModuleFactory(MFoe foe) {
			module = new ControlModule(foe);
		}
		public ControlModule create() {
			module.foe.addBuff(module);
			return module;
		}
	}
}
